package impl

import (
	"adam2/internal/domain"
	"adam2/internal/model"
	"adam2/internal/properties"
	"anubis-framework/pkg/io"
	"anubis-framework/pkg/util"
	"fmt"
	"github.com/vicanso/go-charts/v2"
	"io/ioutil"
	"math"
	"strconv"
)

type QuantAccountLogServiceImpl struct {
	*BaseServiceImpl
}

func GetQuantAccountLogServiceImpl() *QuantAccountLogServiceImpl {
	return &QuantAccountLogServiceImpl{GetBaseServiceImpl()}
}

// 打印最大回撤
func (_quantAccountLogServiceImpl *QuantAccountLogServiceImpl) PrintMaximumDrawdown() {
	io.Infoln("计算最大回撤")

	var maximumDrawdownArray domain.MaximumDrawdownArray = _quantAccountLogServiceImpl._quantAccountLogDaoImpl.CalculateMaximumDrawdown()
	if maximumDrawdownArray != nil && len(maximumDrawdownArray) != 0 {
		for _, maximumDrawdown := range maximumDrawdownArray {
			var num, _ = strconv.ParseFloat(fmt.Sprintf("%.5f", maximumDrawdown.MaximumDrawdown), 64)
			fmt.Printf("最大回撤：%f，开始时间：%s，结束时间：%s，账号：%s\n", num, util.DateToString(maximumDrawdown.Date1), util.DateToString(maximumDrawdown.Date2), maximumDrawdown.AccountName)
		}
	}
}

// 根据表quant_account_log中每个账号的总资金，生成折线图
func (_quantAccountLogServiceImpl *QuantAccountLogServiceImpl) CreateQuantAccountLogLineChart() error {
	io.Infoln("根据表quant_account_log中每个账号的总资金，生成折线图")

	// 查询记录
	var quantAccountLogArray model.QuantAccountLogArray = _quantAccountLogServiceImpl._quantAccountLogDaoImpl.FindByBeginDateAndEndDateOrderByDateAndAccountName(
		properties.ChartProperties_.QuantAccountLogBeginDate, properties.ChartProperties_.QuantAccountLogEndDate)

	if quantAccountLogArray != nil && len(quantAccountLogArray) > 0 {
		// X轴，日期数组
		var xValueArray []string
		// 四个账号的收益数组
		var account1Array []float64
		var account2Array []float64
		var account3Array []float64
		var account4Array []float64

		for index, quantAccountLog := range quantAccountLogArray {
			if (index+1)%4 == 0 {
				xValueArray = append(xValueArray, util.DateToString(quantAccountLog.Date))
				account1Array = append(account1Array, math.Log(quantAccountLog.TotalAssets/float64(properties.ChartProperties_.QuantAccountLogLineChartInitAssets)*100))
			}
			if (index+1)%4 == 1 {
				account2Array = append(account2Array, math.Log(quantAccountLog.TotalAssets/float64(properties.ChartProperties_.QuantAccountLogLineChartInitAssets)*100))
			}
			if (index+1)%4 == 2 {
				account3Array = append(account3Array, math.Log(quantAccountLog.TotalAssets/float64(properties.ChartProperties_.QuantAccountLogLineChartInitAssets)*100))
			}
			if (index+1)%4 == 3 {
				account4Array = append(account4Array, math.Log(quantAccountLog.TotalAssets/float64(properties.ChartProperties_.QuantAccountLogLineChartInitAssets)*100))
			}
		}

		// Y轴，四个账号的收益的二维数组
		var yValueArray [][]float64 = [][]float64{account1Array, account2Array, account3Array, account4Array}

		p, err := charts.LineRender(
			yValueArray,
			charts.FontFamilyOptionFunc("noto"),
			charts.TitleTextOptionFunc("根据表quant_account_log中每个账号的总资金，生成折线图"),
			charts.XAxisDataOptionFunc(xValueArray),
			charts.ThemeOptionFunc("grafana"),
			charts.WidthOptionFunc(2000),
			charts.LegendLabelsOptionFunc([]string{"炒股养家", "宁波桑田路", "章盟主", "赵老哥"}),
			charts.HeightOptionFunc(1000),
		)
		if err != nil {
			panic(err)
		}

		_bytes, _ := p.Bytes()
		ioutil.WriteFile(properties.ChartProperties_.QuantAccountLogLineChartPath+"_"+properties.ChartProperties_.QuantAccountLogBeginDate+"_"+
			properties.ChartProperties_.QuantAccountLogEndDate+
			properties.ChartProperties_.QuantAccountLogLineChartSuffix, _bytes, 0644)
	}

	return nil
}

// 根据给定账号，创建总资产牛熊线折线图
func (_quantAccountLogServiceImpl *QuantAccountLogServiceImpl) CreateQuantAccountLogBullShortLineChart() error {
	var beginDate string = properties.ChartProperties_.QuantAccountLogBullShortLineBeginDate
	var endDate string = properties.ChartProperties_.QuantAccountLogBullShortLineEndDate
	io.Infoln("根据给定账号，创建总资产牛熊线折线图，时间区间为[%s]至[%s]", beginDate, endDate)

	// 查询记录
	var quantAccountLogArray model.QuantAccountLogArray = _quantAccountLogServiceImpl._quantAccountLogDaoImpl.FindByBeginDateAndEndDateAndAccountNameOrderByDateAndAccountName(
		properties.ChartProperties_.QuantAccountLogBullShortLineBeginDate, properties.ChartProperties_.QuantAccountLogBullShortLineEndDate,
		properties.ChartProperties_.QuantAccountLogBullShortLineAccountName)

	if len(quantAccountLogArray) != 0 {
		var dateArray []string
		var averageTotalAssetsArray []float64
		var averageBullShortLineArray []float64

		var topLimit float64 = properties.ChartProperties_.QuantAccountLogBullShortLineByBiasTopLimit
		var bottomList float64 = properties.ChartProperties_.QuantAccountLogBullShortLineByBiasBottomLimit

		for _, quantAccountLog := range quantAccountLogArray {
			var totalAssets float64 = quantAccountLog.TotalAssets
			var bias5 float64 = quantAccountLog.Bias5
			var bias10 float64 = quantAccountLog.Bias10
			var bias20 float64 = quantAccountLog.Bias20
			var bias60 float64 = quantAccountLog.Bias60
			var bias120 float64 = quantAccountLog.Bias120
			var bias250 float64 = quantAccountLog.Bias250

			if bias250 != 0 && bias250 <= topLimit && bias250 >= bottomList {
				averageBullShortLineArray = append(averageBullShortLineArray, quantAccountLog.Ma250)
			} else if bias120 != 0 && bias120 <= topLimit && bias120 >= bottomList {
				averageBullShortLineArray = append(averageBullShortLineArray, quantAccountLog.Ma120)
			} else if bias60 != 0 && bias60 <= topLimit && bias60 >= bottomList {
				averageBullShortLineArray = append(averageBullShortLineArray, quantAccountLog.Ma60)
			} else if bias20 != 0 && bias20 <= topLimit && bias20 >= bottomList {
				averageBullShortLineArray = append(averageBullShortLineArray, quantAccountLog.Ma20)
			} else if bias10 != 0 && bias10 <= topLimit && bias10 >= bottomList {
				averageBullShortLineArray = append(averageBullShortLineArray, quantAccountLog.Ma10)
			} else if bias5 != 0 && bias5 <= topLimit && bias5 >= bottomList {
				averageBullShortLineArray = append(averageBullShortLineArray, quantAccountLog.Ma5)
			} else {
				averageBullShortLineArray = append(averageBullShortLineArray, totalAssets)
			}

			dateArray = append(dateArray, util.DateToString(quantAccountLog.Date))
			averageTotalAssetsArray = append(averageTotalAssetsArray, totalAssets)
		}

		// Y轴，四个账号的收益的二维数组
		var yValueArray [][]float64 = [][]float64{averageTotalAssetsArray, averageBullShortLineArray}

		p, err := charts.LineRender(
			yValueArray,
			charts.FontFamilyOptionFunc("noto"),
			charts.TitleTextOptionFunc("根据每个账号，创建总资产牛熊线折线图"),
			charts.XAxisDataOptionFunc(dateArray),
			charts.ThemeOptionFunc("grafana"),
			charts.WidthOptionFunc(2000),
			charts.LegendLabelsOptionFunc([]string{"total_assets", "bull short line"}),
			charts.HeightOptionFunc(1000),
		)
		if err != nil {
			panic(err)
		}

		_bytes, _ := p.Bytes()
		ioutil.WriteFile(properties.ChartProperties_.QuantAccountLogBullShortLineChartPath+"_"+properties.ChartProperties_.QuantAccountLogBullShortLineAccountName+"_"+
			properties.ChartProperties_.QuantAccountLogBullShortLineBeginDate+"_"+properties.ChartProperties_.QuantAccountLogBullShortLineEndDate+
			properties.ChartProperties_.QuantAccountLogBullShortLineChartSuffix, _bytes, 0644)
	}

	return nil
}
